/*
 * CcBlockInfo.c
 *
 *  Created on: 2012/05/03
 *      Author: guanxiaoying
 */

#include "../coredef.h"
#include "cc.h"

VOID  CcBlockInitial( VOID ){
	if( stBlockNestAccess.getMax() > 0 ){
		stBlockNestAccess.clear();
		stCCDefSymChainAccess.clear();
	}
	stBlockNestAccess.alloc(1);
}
AST  CcBlockGetCurrInnermostOne(VOID){
	return stBlockNestAccess.getMax();
}
AST  CcBlockAddNewTag( AST astBlock, PSZ name ){
	AST  astTagRoot ;
	AST  astNewCcDefChain;
	AST  astNewSym;

	if( astBlock < MIN_ARRAY || name == NULL ){
		return( 0 ) ;
	}
	astTagRoot = stBlockNestAccess.tagRoot.get( astBlock );
	astNewCcDefChain = stCCDefSymChainAccess.insert( astTagRoot, &astTagRoot, name );
	stBlockNestAccess.tagRoot.set(astBlock, astTagRoot);

	astNewSym = CcSymNewTagName( name );

	stCCDefSymChainAccess.parameter.set( astNewCcDefChain, astNewSym );
	return astNewSym;
}
AST  CcBlockAddNewEnumSymbol( AST astBlock, PSZ name ){
	AST  astTagRoot ;
	AST  astNewCcDefChain;
	AST  astNewSym;

	if( astBlock < MIN_ARRAY || name == NULL ){
		return( 0 ) ;
	}
	astTagRoot = stBlockNestAccess.symRoot.get( astBlock );
	astNewCcDefChain = stCCDefSymChainAccess.insert( astTagRoot, &astTagRoot, name );
	stBlockNestAccess.symRoot.set(astBlock, astTagRoot);

	astNewSym = CcSymNewEnumConst(name);

	stCCDefSymChainAccess.parameter.set( astNewCcDefChain, astNewSym );
	return astNewSym;
}
AST  CcBlockAddNewSymbol( AST astBlock, PSZ name ){
	AST  astTagRoot ;
	AST  astNewCcDefChain;
	AST  astNewSym;

	if( astBlock < MIN_ARRAY || name == NULL ){
		return( 0 ) ;
	}
	astTagRoot = stBlockNestAccess.symRoot.get( astBlock );
	astNewCcDefChain = stCCDefSymChainAccess.insert( astTagRoot, &astTagRoot, name );
	stBlockNestAccess.symRoot.set(astBlock, astTagRoot);

	astNewSym = CcSymNewUnknown( name );
	stCCDefSymChainAccess.parameter.set( astNewCcDefChain, astNewSym );
	return astNewSym;
}
VOID  CcBlockAddExistSymbol( AST astBlock, AST astSym ){
	AST  astTagRoot ;
	AST  astNewCcDefChain;

	if( astBlock < MIN_ARRAY || astSym == 0 ){
		return;
	}
	astTagRoot = stBlockNestAccess.symRoot.get( astBlock );
	astNewCcDefChain = stCCDefSymChainAccess.insert( astTagRoot, &astTagRoot,
			stSymbolInfoAccess.name.get( astSym ) );
	stBlockNestAccess.symRoot.set(astBlock, astTagRoot);
	stCCDefSymChainAccess.parameter.set( astNewCcDefChain, astSym );
}
AST  CcBlockAddLabelStatement( PSZ name ){
	AST  astBlock = MIN_ARRAY+1;
	AST  astTagRoot ;
	AST  astNewCcDefChain;
	AST  astNewSym;
	AST  astLabelStmt;

	if( stBlockNestAccess.getMax() < astBlock || name == NULL ){
		return( 0 ) ;
	}
	astTagRoot = stBlockNestAccess.labelRoot.get( astBlock );
	astNewCcDefChain = stCCDefSymChainAccess.insert( astTagRoot, &astTagRoot, name );
	stBlockNestAccess.labelRoot.set(astBlock, astTagRoot);

	stStatementAccess.alloc(1);
	astLabelStmt = stStatementAccess.getMax();

	stStatementAccess.statmentKind.set( astLabelStmt, xSTMT_LABEL );
	astNewSym = CcSymNewLabel( name );
	stStatementAccess.label_name.set( astLabelStmt, astNewSym );
	stSymbolInfoAccess.value.set( astNewSym, astLabelStmt );
	stCCDefSymChainAccess.parameter.set( astNewCcDefChain, astNewSym );
	return astLabelStmt;
}
AST  CcBlockFindTag( PSZ name, AST * block ){
	AST	astBlockNest ;		/*ブロックネスト数*/
	S4	astSymDeclChain ; 	/*シンボル定義チェーン*/

	astBlockNest = stBlockNestAccess.getMax();

	while( astBlockNest >= MIN_ARRAY ){
		astSymDeclChain = stBlockNestAccess.tagRoot.get( astBlockNest );
		astSymDeclChain = stCCDefSymChainAccess.find( astSymDeclChain, name );
		if( astSymDeclChain >= MIN_ARRAY ){
			if( block != NULL ){
				*block = astBlockNest;
			}
			return( stCCDefSymChainAccess.parameter.get(astSymDeclChain) );
		}
		astBlockNest--;
	}
	return( 0L );
}
AST  CcBlockFindLabel( PSZ name, AST * block ){
	AST	astBlockNest ;		/*ブロックネスト数*/
	S4	astSymDeclChain ; 	/*シンボル定義チェーン*/

	astBlockNest = stBlockNestAccess.getMax();

	if( astBlockNest >= MIN_ARRAY + 1 ){
		astSymDeclChain = stBlockNestAccess.labelRoot.get( MIN_ARRAY + 1 );
		astSymDeclChain = stCCDefSymChainAccess.find( astSymDeclChain, name );
		if( astSymDeclChain >= MIN_ARRAY ){
			if( block != NULL ){
				*block = MIN_ARRAY + 1;
			}
			return( stCCDefSymChainAccess.parameter.get(astSymDeclChain) );
		}
	}
	return( 0L );
}
AST  CcBlockFindSymbol( PSZ name, AST * block ){
	AST	astBlockNest ;		/*ブロックネスト数*/
	S4	astSymDeclChain ; 	/*シンボル定義チェーン*/

	astBlockNest = stBlockNestAccess.getMax();

	while( astBlockNest >= MIN_ARRAY ){
		astSymDeclChain = stBlockNestAccess.symRoot.get( astBlockNest );
		astSymDeclChain = stCCDefSymChainAccess.find( astSymDeclChain, name );
		if( astSymDeclChain >= MIN_ARRAY ){
			if( block != NULL ){
				*block = astBlockNest;
			}
			return( stCCDefSymChainAccess.parameter.get(astSymDeclChain) );
		}
		astBlockNest--;
	}
	return( 0L );
}
VOID  CcBlockEntryBlock( VOID ){
	stBlockNestAccess.alloc(1);
	/* It's not a stack(nest) because of label statements */
//	stBlockNestAccess.beginCcDefChain.set( stBlockNestAccess.getMax(),
//			stCCDefSymChainAccess.getMax() + 1 );
}
VOID  CcBlockQuitBlock( VOID ){
	stBlockNestAccess.alloc(-1);
	/* It's not a stack(nest) because of label statements */
//	stBlockNestAccess.alloc( astCcDefChain - stCCDefSymChainAccess.getMax() - 1  );
}
